/* main.c */

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <signal.h>

#include "protocol.h"
#include "process.h" 

#define MAX_CLIENTS 100
#define BUFFER_SIZE 512


#define MAX_CLIENT 256

#define PERM 0666
#define C2S_KEY 9999
#define S2C_KEY 9998
#define MAX_MSG_LEN 512

int fd2id_flag[MAX_CLIENT];
int id2fd_flag[MAX_CLIENT];
int fd2id_array[MAX_CLIENT];
int id2fd_array[MAX_CLIENT];

int fd2id(int);
int id2fd(int);

static int c2s_id;
static int s2c_id;



typedef struct msg_data{
	long type;
	char text[MAX_MSG_LEN];
} msg_data_t;


int send_msg(int fd, const char * msg);

static void init_msgs();
static void delete_msgs();

void sigint_handler(int);


int main()
{
    
    char buffer[BUFFER_SIZE];
    
    protocol_t in_msg;
    protocol_t out_msg;
    
    msg_data_t data_recv;
    msg_data_t data_send;
    
    tbs_init();
    
    init_msgs();
      
    if(signal(SIGINT, sigint_handler) == SIG_ERR ){
    	perror("Cannot register singnal handler");
    	tbs_end();
    }

	while(1) {
		int id = 0;
		int len = 0;

		if (msgrcv(c2s_id, (void *)&data_recv, MAX_MSG_LEN, 0, 0) == -1) {
		    perror("msgrcv failed with error");
		    exit(-1);
		}
		
		id = data_recv.type;
		printf("client process id: %d", id);
		if(parse_msg(&in_msg, data_recv.text) != 0){
			fprintf(stderr,"Cannot parse messege!");
			continue;
		}
		if(process_action(id, &in_msg, &out_msg, send_msg)!=0){
				continue;
		}
		//send msg
		format_msg(&out_msg, buffer);
		printf("Formatted String[%s]\n", buffer);
		printf("id = %d\n", out_msg.usr_id);
		len = strlen(buffer);
		data_send.type = id;
		strcpy(data_send.text, buffer);
		msgsnd(s2c_id, &data_send, len + 1, 0);
	}
	tbs_end();
}


int send_msg(int fd, const char * msg){
	int len = strlen(msg);
	msg_data_t send_data;
	send_data.type = fd;
	printf("Formatted String[%s]\n", msg);
	strcpy(send_data.text, msg);
	msgsnd(s2c_id, &send_data, len + 1, 0);
	return 0;
}

int fd2id(int i){
	if(fd2id_flag[i] != 1){
		return -1;
	}else {
		return fd2id_array[i];
	}
}

int id2fd(int i){
	if(id2fd_flag[i] != 1){
		return -1;
	}else {
		return id2fd_array[i];
	}
}

void sigint_handler(int sig) {
	if(sig == SIGINT){
		tbs_end();
		delete_msgs();
		printf("shutting down server ... ");
		exit(0);
	}
	return;
}


void init_msgs()
{
    if ((c2s_id = 
	msgget(C2S_KEY, PERM | IPC_CREAT)) < 0) {
	perror("MSG Key");
	exit(-1);
    }
    if ((s2c_id = 
	msgget(S2C_KEY, PERM | IPC_CREAT)) < 0) {
	perror("MSG Key");
	exit(-1);
    }
}

void delete_msgs()
{
    msgctl(c2s_id, IPC_RMID, 0);
    msgctl(s2c_id, IPC_RMID, 0);
}


